import time
import cv2
import numpy as np
import Processor.Converter as Converter

from PyQt5.QtWidgets import QDialog
from Plugin.EffectFilter.SoftSkin_design import Ui_SoftSkinController


class SoftSkinController(QDialog, Ui_SoftSkinController):
    layer = None  # 图层
    mat = None  # 原始Mat 数据

    def __init__(self, parent, mat=None):
        super().__init__(parent)
        self.setupUi(self)
        self.__initUI(parent)
        self.mat = mat

    def reject(self):
        """
        取消操作
        :return:
        """
        image = Converter.Numpy2QImage(self.mat)
        self.layer.updatePixmap(image)
        QDialog.reject(self)

    def __initUI(self, parent):
        self.setWindowTitle('磨皮')
        # 定位
        self.resize(180, 170)
        pos = parent.geometry()
        self.move((pos.width() - self.width()) / 2, (pos.height() - self.height()) / 2)
        # 信号
        #       对话框确定
        self.DialogButtonBox.accepted.connect(self.accept)
        self.DialogButtonBox.rejected.connect(self.reject)
        self.horizontalSlider_soft_kSize.valueChanged.connect(self.updateSlot)
        self.horizontalSlider_highpass_kSize.valueChanged.connect(self.updateSlot)
        self.horizontalSlider_detail_blur.valueChanged.connect(self.updateSlot)
        self.horizontalSlider_alpha.valueChanged.connect(self.updateSlot)

    def updateSlot(self):
        soft_kSize = self.horizontalSlider_soft_kSize.value()
        if soft_kSize % 2 == 0:
            soft_kSize = soft_kSize - 1
        highpass_kSize = self.horizontalSlider_highpass_kSize.value()
        if highpass_kSize % 2 == 0:
            highpass_kSize = highpass_kSize - 1
        detail_blur = self.horizontalSlider_detail_blur.value()
        if detail_blur % 2 == 0:
            detail_blur = detail_blur - 1
        alpha = self.horizontalSlider_alpha.value()
        self.label_soft_kSize.setText(str(soft_kSize))
        self.label_highpass_kSize.setText(str(highpass_kSize))
        self.label_detail_blur.setText(str(detail_blur))
        self.label_alpha.setText(str(alpha))
        self.blur(soft_kSize, highpass_kSize, detail_blur, alpha/100)

    def blur(self, soft_kSize, highpass_kSize, detail_blur=1, alpha=0.7):
        """
        :param soft_kSize: 高斯双边模糊半径
        :param highpass_kSize: 高反差模糊半径
        :param detail_blur: 细节模糊半径
        :param alpha: 线性光叠加透明度
        :return:
        """
        start = time.perf_counter()
        mat = self.mat.copy()
        data = np.float32(mat[..., 0:3])
        # 高反差
        highpass = cv2.GaussianBlur(data, ksize=(highpass_kSize, highpass_kSize), sigmaX=0, sigmaY=0)
        highpass = data - highpass + 128
        # 高反差平滑
        if detail_blur > 1:
            highpass = cv2.GaussianBlur(highpass, (detail_blur, detail_blur), 0)
        # 模糊原图
        data = cv2.bilateralFilter(data, soft_kSize, soft_kSize * 3, soft_kSize * 3)
        # 线性光叠加
        # 基色 + 2混合色 - 255 = 结果色。
        dst = data + 2 * highpass - 255
        # 透明度叠加
        dst = cv2.addWeighted(data, alpha, dst, 1 - alpha, 0)

        mat[..., 0:3] = np.uint8(np.clip(dst, 0, 255))
        image = Converter.Numpy2QImage(mat)
        end = time.perf_counter()
        print('SoftSkin', '耗时：', end - start)
        self.layer.updatePixmap(image)
